package projects

import (
	"encoding/json"
	"fmt"
	"github.com/360EntSecGroup-Skylar/excelize/v2"
	"github.com/beego/beego/v2/core/validation"
	beego "github.com/beego/beego/v2/server/web"
	"github.com/beego/beego/v2/server/web/pagination"
	"github.com/jinzhu/copier"
	"log"
	"os"
	"strconv"
	"strings"
	"time"
	"xpms/app/dict"
	"xpms/controllers"
	"xpms/cores"
	"xpms/cores/utils"
)

//  反馈管理
type TestProjectController struct {
	controllers.BaseController
}

// @Title 分页查询项目模块数据
// @Description 分页查询项目模块数据
// @Param	id		path 	string	true		"项目id"
// @Param	p		query 	int	true		"第几页"
// @Param	pageoffset		query 	int			"每页数"
// @Param	status		query 	[]string			"状态"
// @Param	keywords		query 	string			"名称"
// @Param	acceptid		query 	[]string			"指派人"
// @Param	completeid		query 	[]string			"完成人"
// @Param	projectmoduleid		query 	[]string			"模块"
// @Param	type		query 	[]string			"分类"
// @Param	level		query 	[]string			"级别"
// @Param	creatId		query 	[]string			"创建人"
// @Param	env		query 	[]string			"环境"
// @Param	createStarted		query 	int64			"创建开始时间"
// @Param	createEnd		query 	int64			"创建结束时间"
// @Param	estimatedtasktimestart		query 	int64			"开始估算工时"
// @Param	estimatedtasktimestartend		query 	int64			"结束估算工时"
// @Param	bussconfirmstatus		query 	[]string				"业务确认状态"
// @Param	testno		query 	string				"反馈编号"
// @Param	vesionno		query 	string				"版本或者分支"
// @Param	acceptevn		query 	string				"验收环境"
// @Param	filter		query 	string				"快速过滤 create：我创建 complete:我完成  accept:指派给我 unaccept:未指派"
// @Param	departid		query 	[]string			"创建人部门"
// @Param	uatdepart		query 	[]string			"验收部门"
// @Success 200 {object} projects.ProjectsAllTestDto   int   int  int
// @Failure 403 module not exist
// @router /:id/page [get]
func (u *TestProjectController) Page() {
	id, err := u.GetInt64(":id")
	if err != nil || id < 0 {
		// handle error
		u.Data["json"] = map[string]interface{}{"code": 0, "message": "未知项目" + err.Error()}
		u.ServeJSON()
		return
	}
	userid := u.BaseController.UserUserId
	status := u.GetStrings("status")
	keywords := u.GetString("keywords")
	acceptid := u.GetStrings("acceptid")
	completeid := u.GetStrings("completeid")
	projectmoduleid := u.GetStrings("moduleid")
	departid := u.GetStrings("departid")
	typec := u.GetStrings("type")
	level := u.GetStrings("level")
	creatId := u.GetStrings("creatId")
	env := u.GetStrings("env")
	group := u.GetStrings("group")
	createStarted := u.GetString("createStarted")
	createEnd := u.GetString("createEnd")
	estimatedtasktimestart := u.GetString("estimatedtasktimestart")
	estimatedtasktimestartend := u.GetString("estimatedtasktimestartend")
	bussconfirmstatus := u.GetStrings("bussconfirmstatus")
	testno := u.GetString("testno")
	vesionno := u.GetString("vesionno")
	uatdepart := u.GetStrings("uatdepart")
	acceptevn := u.GetStrings("acceptevn")

	page, err := u.GetInt("p")
	offset, err := u.GetInt("pageoffset")
	if err != nil {
		offset = 15
	}
	filter := u.GetString("filter")
	condArr := make(map[string]interface{})
	condArr["projectid"] = id
	condArr["status"] = status
	condArr["keywords"] = keywords
	condArr["acceptid"] = acceptid
	condArr["type"] = typec
	condArr["level"] = level
	condArr["env"] = env
	condArr["completeid"] = completeid
	condArr["projectmoduleid"] = projectmoduleid
	condArr["group"] = group
	condArr["createStarted"] = createStarted
	condArr["createEnd"] = createEnd
	condArr["bussconfirmstatus"] = bussconfirmstatus
	condArr["estimatedtasktimestart"] = estimatedtasktimestart
	condArr["estimatedtasktimestartend"] = estimatedtasktimestartend
	condArr["testno"] = testno
	condArr["departid"] = departid
	condArr["vesionno"] = vesionno
	condArr["uatdepart"] = uatdepart
	condArr["acceptevn"] = acceptevn

	if filter == "create" {
		condArr["userid"] = userid
		condArr["creatId"] = userid
	} else if !utils.IsEmpty(creatId) {
		condArr["userid"] = creatId
		condArr["creatId"] = creatId
	} else if filter == "complete" {
		condArr["completeid"] = userid
	} else if filter == "accept" {
		condArr["acceptid"] = userid
		filter = "accept"
	}
	condArr["filter"] = filter
	countTest := TestPageCountExec(condArr, page, offset)
	paginator := pagination.SetPaginator(u.Ctx, offset, countTest)
	modeData := TestPageExec(condArr, page, offset)

	type data struct {
		Tests    []ProjectsAllTestDto
		Total    int64
		PageNums int
		Page     int
	}
	d := &data{modeData, paginator.Nums(), paginator.PageNums(), paginator.Page()}
	var responseEntity cores.ResponseEntity
	u.Data["json"] = responseEntity.Build(d).Data
	u.Ctx.Output.Status = responseEntity.StatusCode
	u.ServeJSON()
}

type TestDTO struct {
	Taskid                int64 `json:"Taskid,string"`
	Needsid               int64 `json:"Needsid,string"`
	Projectid             int64 `json:"Projectid,string"`
	Userid                int64 `json:"Userid,string"`
	Acceptid              int64 `json:"Acceptid,string"`
	Ccid                  []string
	Completeid            int64 `json:"Completeid,string"`
	Type                  int   `json:"Type,string"`
	Name                  string
	Desc                  string
	Level                 int `json:"Level,string"`
	DirectCause           string
	RootCause             string
	RootCauseType         int
	CorrespondingStrategy string
	EvasiveStrategy       string
	Attachment            string
	Completed             int64
	Os                    string
	Browser               string
	Created               int64
	Changed               int64
	Status                int   `json:"Status,string"`
	Projectmoduleid       int64 `json:"Projectmoduleid,string"`
	Env                   int   `json:"Env,string"`
	Estimatedtasktime     int
	Actualtasktime        int
	Bussconfirmstatus     int
	Acceptevn             int `json:"Acceptevn,string"`
	Note                  string
}

// 如果你的 struct 实现了接口 validation.ValidFormer
// 当 StructTag 中的测试都成功时，将会执行 Valid 函数进行自定义验证
func (u *TestDTO) Valid(v *validation.Validation) {
	v.Required(u.Name, "Name").Message("标题不能为空")
	v.Required(u.Type, "Type").Message("分类不能为空")
	v.Required(u.Level, "Level").Message("级别不能为空")
	v.Required(u.Projectmoduleid, "Projectmoduleid").Message("模块不能为空")
	//v.Required(u.Env, "Env").Message("环境不能为空")
}

// @Title Create test
// @Description create test
// @Param	body		body 	projects.TestDTO	true		"body for test content"
// @Success 200 {int} projects.ProjectsTest.Id
// @Failure 403 body is empty
// @router / [post]
func (u *TestProjectController) Create() {
	var f TestDTO
	err := json.Unmarshal(u.Ctx.Input.RequestBody, &f)
	// 开始校验输入值
	valid := validation.Validation{}
	b, err := valid.Valid(&f)
	valid.Required(f.Projectid, "Projectid").Message("项目id为空")
	if err != nil {
		// handle error
		u.Data["json"] = map[string]interface{}{"code": 0, "message": "严重异常" + err.Error()}
		u.ServeJSON()
		return
	}
	if !b {
		var validMsg []string
		// validation does not pass
		for _, err := range valid.Errors {
			validMsg = append(validMsg, err.Message)
			log.Println(err.Key, err.Message)
		}
		if !utils.IsEmpty(validMsg) {
			u.Data["json"] = map[string]interface{}{"code": 0, "message": strings.Join(validMsg, ",")}
			u.ServeJSON()
			return
		}
	}
	userid := u.BaseController.UserUserId
	//雪花算法ID生成
	id := utils.SnowFlakeId()
	test := new(ProjectsTest)
	copier.Copy(test, f)
	test.Id = id
	test.Userid = userid
	test.Uatdepart = u.BaseController.Departid
	test.Ccid = strings.Join(f.Ccid, ",")
	needtype := [...]int64{2, 3, 10}
	ok, found := utils.IncludeElement(needtype, test.Type)
	if ok && found {
		test.Status = 10
	} else {
		test.Status = 21
	}
	err = AddTest(*test)
	if err == nil {
		u.Data["json"] = map[string]interface{}{"code": 1, "message": "反馈添加成功", "id": fmt.Sprintf("%d", id)}
	} else {
		u.Data["json"] = map[string]interface{}{"code": 0, "message": "反馈添加失败" + err.Error()}
	}
	u.ServeJSON()

}

// @Title Update Test
// @Description   Update Test
// @Param	id		path 	string	true		"test id"
// @Param	body		body 	projects.TestDTO	true		"body for test content"
// @Success 200 {string} 更新成功
// @Failure 403 body is empty
// @router /:id [put]
func (u *TestProjectController) Update() {
	ids, err := u.GetInt64(":id")
	if err != nil || ids <= 0 {
		u.Data["json"] = map[string]interface{}{"code": 0, "message": "你选择更新的反馈为空"}
		u.ServeJSON()
		return
	}
	var f TestDTO
	err = json.Unmarshal(u.Ctx.Input.RequestBody, &f)
	// 开始校验输入值
	valid := validation.Validation{}
	b, err := valid.Valid(&f)
	if err != nil {
		// handle error
		u.Data["json"] = map[string]interface{}{"code": 0, "message": "严重异常" + err.Error()}
		u.ServeJSON()
		return
	}
	if !b {
		var validMsg []string
		// validation does not pass
		for _, err := range valid.Errors {
			validMsg = append(validMsg, err.Message)
			log.Println(err.Key, err.Message)
		}
		if !utils.IsEmpty(validMsg) {
			u.Data["json"] = map[string]interface{}{"code": 0, "message": strings.Join(validMsg, ",")}
			u.ServeJSON()
			return
		}
	}
	userss, err1 := GetProjectTest(ids)
	if err1 != nil || utils.IsEmpty(userss.Name) {
		u.Data["json"] = map[string]interface{}{"code": 0, "message": "反馈不存在"}
		u.ServeJSON()
		return
	}

	test := new(ProjectsTest)
	utils.SimpleCopyProperties(test, f)
	test.Ccid = strings.Join(f.Ccid, ",")
	err = UpdateTest(ids, u.UserUserId, *test)
	if err == nil {
		u.Data["json"] = map[string]interface{}{"code": 1, "message": "信息修改成功", "id": fmt.Sprintf("%d", ids)}
	} else {
		u.Data["json"] = map[string]interface{}{"code": 0, "message": "信息修改失败" + err.Error()}
	}
	u.ServeJSON()
}

// @Title Get
// @Description get test  by id
// @Param	id		path 	string	true		"The key for test"
// @Success 200 {object} projects.ProjectsTest
// @Failure 403 :id is empty
// @router /:id [get]
func (u *TestProjectController) Get() {
	condArr := make(map[string]interface{})
	condArr["testno"] = u.GetString(":id")
	condArr["testid"] = u.GetString(":id")
	countTest := TestPageCountExec(condArr, 1, 1)
	paginator := pagination.SetPaginator(u.Ctx, 1, countTest)
	modeData := TestPageExec(condArr, 1, 1)

	type data struct {
		Tests    []ProjectsAllTestDto
		Total    int64
		PageNums int
		Page     int
	}
	d := &data{modeData, paginator.Nums(), paginator.PageNums(), paginator.Page()}
	var responseEntity cores.ResponseEntity
	u.Data["json"] = responseEntity.Build(d).Data
	u.Ctx.Output.Status = responseEntity.StatusCode
	u.ServeJSON()

}

// @Title Update test buss status
// @Description  Update test buss status
// @Param	id		path 	string	true		"test id"
// @Param	body	body 	projects.TestAcceptDTO	true		"Buss 状态"
// @Success 200 {string} 更新成功
// @Failure 403 body is empty
// @router /:id/buss/status [put]
func (u *TestProjectController) UpdateBussStatus() {
	ids, err := u.GetInt64(":id")
	if err != nil || ids <= 0 {
		u.Data["json"] = map[string]interface{}{"code": 0, "message": "你选择更新的反馈为空"}
		u.ServeJSON()
		return
	}
	var f TestAcceptDTO
	err = json.Unmarshal(u.Ctx.Input.RequestBody, &f)
	if err != nil {
		u.Data["json"] = map[string]interface{}{"code": 0, "message": "状态为空"}
		u.ServeJSON()
		return
	}
	test, err1 := GetProjectTest(ids)
	if err1 != nil || utils.IsEmpty(test.Name) {
		u.Data["json"] = map[string]interface{}{"code": 0, "message": "反馈不存在"}
		u.ServeJSON()
		return
	}
	test.Bussconfirmstatus = f.Status
	if f.Status == 2 {
		test.Status = 0
	}
	err = UpdateTest(ids, u.UserUserId, test)
	if err == nil {
		u.Data["json"] = map[string]interface{}{"code": 1, "message": "信息修改成功", "id": fmt.Sprintf("%d", ids)}
	} else {
		u.Data["json"] = map[string]interface{}{"code": 0, "message": "信息修改失败" + err.Error()}
	}
	u.ServeJSON()
}

type TestAcceptDTO struct {
	Acceptid  int64 `json:"Acceptid,string"`
	Note      string
	Status    int   `json:"Status,string"`
	Uatdepart int64 `json:"Uatdepart,string"`
	Type      int   //指派类型
}

// @Title Update test accept
// @Description  Update test accept
// @Param	id		path 	string	true		"test id"
// @Param	body	body 	projects.TestAcceptDTO	true		"指派人员"
// @Param	note	query 	string			"直接原因"
// @Success 200 {string} 更新成功
// @Failure 403 body is empty
// @router /:id/accept [put]
func (u *TestProjectController) UpdateAccept() {
	ids, err := u.GetInt64(":id")
	if err != nil || ids <= 0 {
		u.Data["json"] = map[string]interface{}{"code": 0, "message": "你选择更新的反馈为空"}
		u.ServeJSON()
		return
	}
	var f TestAcceptDTO
	err = json.Unmarshal(u.Ctx.Input.RequestBody, &f)
	err = ChangeProjectTestAccept(ids, u.BaseController.UserUserId, f)
	if err == nil {
		u.Data["json"] = map[string]interface{}{"code": 1, "message": "信息修改成功", "id": fmt.Sprintf("%d", ids)}
	} else {
		u.Data["json"] = map[string]interface{}{"code": 0, "message": "信息修改失败" + err.Error()}
	}
	u.ServeJSON()
}

type TestStatusDTO struct {
	Taskid                int64 `json:"Taskid,string"`
	Acceptid              int64 `json:"Acceptid,string"`
	Type                  int   `json:"Type,string"`
	DirectCause           string
	RootCause             string
	RootCauseType         int `json:"RootCauseType,string"`
	CorrespondingStrategy string
	EvasiveStrategy       string
	Status                int `json:"Status,string"`
	Note                  string
	Estimatedtasktime     int `json:"Estimatedtasktime,string"`
	Actualtasktime        int `json:"Actualtasktime,string"`
	Attachmentname        string
	Attachment            string
	Projectid             string
	Vesionno              string
	Acceptevn             int `json:"Acceptevn,string"`
}

// @Title Update test status
// @Description  Update test status
// @Param	id		path 	string	true		"test id"
// @Param	body	body 	projects.TestStatusDTO	true		"Status 必填，EvasiveStrategy CorrespondingStrategy DirectCause Acceptid  RootCause Type RootCauseType Estimatedtasktime  Actualtasktime 根据情况填写"
// @Success 200 {string} 更新成功
// @Failure 403 body is empty
// @router /:id/status [put]
func (u *TestProjectController) UpdateStaus() {
	ids, err := u.GetInt64(":id")
	if ids <= 0 || err != nil {
		u.Data["json"] = map[string]interface{}{"code": 0, "message": "请选择反馈"}
		u.ServeJSON()
		return
	}
	var dto TestStatusDTO
	err = json.Unmarshal(u.Ctx.Input.RequestBody, &dto)
	// 开始校验输入值
	valid := validation.Validation{}
	valid.Required(dto.Projectid, "Projectid").Message("项目id为空")
	b, err := valid.Valid(&dto)
	if err != nil {
		// handle error
		u.Data["json"] = map[string]interface{}{"code": 0, "message": "严重异常" + err.Error()}
		u.ServeJSON()
		return
	}
	if !b {
		var validMsg []string
		// validation does not pass
		for _, err := range valid.Errors {
			validMsg = append(validMsg, err.Message)
			log.Println(err.Key, err.Message)
		}
		if !utils.IsEmpty(validMsg) {
			u.Data["json"] = map[string]interface{}{"code": 0, "message": strings.Join(validMsg, ",")}
			u.ServeJSON()
			return
		}
	}
	// 查看字典 TEST_STATUS 值
	if -1 != dto.Status {
		test := new(ProjectsTestStatus)
		utils.SimpleCopyProperties(test, dto)
		test.Id = ids
		userid := u.BaseController.UserUserId
		test.IfsMail = 1
		err := ChangeProjectTest(userid, *test)
		if err == nil {
			u.Data["json"] = map[string]interface{}{"code": 1, "message": "修改状态成功"}
		} else {
			u.Data["json"] = map[string]interface{}{"code": 0, "message": "修改状态失败" + err.Error()}
		}
	}
	//var err error
	//雪花算法ID生成
	// 如果评论不为空，添加评论信息
	if dto.Note != "<p><br></p>" {
		idn := utils.SnowFlakeId()
		var comment ProjectsTestComments
		comment.Id = idn
		comment.Testid = ids
		userid := u.BaseController.UserUserId
		comment.UserName = u.BaseController.UserUsername
		comment.Userid = userid
		comment.Comment = dto.Note
		comment.Attachmentname = dto.Attachmentname
		comment.Attachment = dto.Attachment
		err := AddTestComments(comment)
		if err == nil {
			u.Data["json"] = map[string]interface{}{"code": 1, "message": "添加评论成功"}
		} else {
			u.Data["json"] = map[string]interface{}{"code": 0, "message": "添加评论失败" + err.Error()}
		}
	}
	u.ServeJSON()
}

// @Title Get
// @Description get test  by id
// @Param	id		path 	string	true		"The key for test"
// @Success 200 {object} projects.ProjectsTestComments
// @Failure 403 :id is empty
// @router /:id/comment [get]
func (u *TestProjectController) GetComment() {
	uid := u.GetString(":id")
	if uid != "" {
		var responseEntity cores.ResponseEntity
		int64, err := strconv.ParseInt(uid, 10, 64)
		if err != nil {
			u.Data["json"] = responseEntity.BuildError(err.Error())
			return
		}
		dbData := ListProjectTestComment(int64)
		if err != nil {
			u.Data["json"] = responseEntity.BuildError(err.Error())
		} else {
			u.Data["json"] = responseEntity.Build(dbData).Data
			u.Ctx.Output.Status = responseEntity.StatusCode
		}
	}
	u.ServeJSON()
}

// @Title Get
// @Description get test  by id
// @Param	id		path 	string	true		"The key for test"
// @Success 200 {object} projects.ProjectsTestLog
// @Failure 403 :id is empty
// @router /:id/log [get]
func (u *TestProjectController) GetLog() {
	uid := u.GetString(":id")
	if uid != "" {
		var responseEntity cores.ResponseEntity
		int64, err := strconv.ParseInt(uid, 10, 64)
		if err != nil {
			u.Data["json"] = responseEntity.BuildError(err.Error())
			return
		}
		condArr := make(map[string]interface{})
		condArr["testid"] = int64
		dbData := TestLogExec(condArr)
		if err != nil {
			u.Data["json"] = responseEntity.BuildError(err.Error())
		} else {
			u.Data["json"] = responseEntity.Build(dbData).Data
			u.Ctx.Output.Status = responseEntity.StatusCode
		}
	}
	u.ServeJSON()
}

// @Title Get
// @Description get EXPORT test  by id
// @Param	id		path 	string	true		"项目id"
// @Param	status		query 	[]string			"状态"
// @Param	keywords		query 	string			"名称"
// @Param	acceptid		query 	[]string			"指派人"
// @Param	completeid		query 	[]string			"完成人"
// @Param	projectmoduleid		query 	[]string			"模块"
// @Param	type		query 	[]string			"分类"
// @Param	level		query 	[]string			"级别"
// @Param	creatId		query 	[]string			"创建人"
// @Param	env		query 	[]string			"环境"
// @Param	createStarted		query 	int64			"创建开始时间"
// @Param	createEnd		query 	int64			"创建结束时间"
// @Param	estimatedtasktimestart		query 	int64			"开始估算工时"
// @Param	estimatedtasktimestartend		query 	int64			"结束估算工时"
// @Param	bussconfirmstatus		query 	[]string				"业务确认状态"
// @Param	testno		query 	string				"反馈编号"
// @Param	departid		query 	[]string			"创建人部门"
// @Success 200 {string}
// @Failure 403 :id is empty
// @router /export/:id [get]
func (this *TestProjectController) ExportGet() {
	idstr := this.Ctx.Input.Param(":id")
	userid := this.BaseController.UserUserId
	status := this.GetStrings("status")
	keywords := this.GetString("keywords")
	acceptid := this.GetStrings("acceptid")
	completeid := this.GetStrings("completeid")
	projectmoduleid := this.GetStrings("moduleid")
	typec := this.GetStrings("type")
	level := this.GetStrings("level")
	creatId := this.GetStrings("creatId")
	env := this.GetStrings("env")
	group := this.GetStrings("group")
	createStarted := this.GetString("createStarted")
	createEnd := this.GetString("createEnd")
	estimatedtasktimestart := this.GetString("estimatedtasktimestart")
	estimatedtasktimestartend := this.GetString("estimatedtasktimestartend")
	bussconfirmstatus := this.GetStrings("bussconfirmstatus")
	testno := this.GetString("testno")
	departid := this.GetStrings("departid")

	filter := this.GetString("filter")
	condArr := make(map[string]interface{})
	if filter == "create" {
		condArr["userid"] = userid
		condArr["creatId"] = userid
	} else if !utils.IsEmpty(creatId) {
		condArr["userid"] = creatId
		condArr["creatId"] = creatId
	} else if filter == "complete" {
		condArr["completeid"] = userid
	} else if filter == "accept" {
		condArr["acceptid"] = userid
		filter = "accept"
	}
	condArr["projectid"] = idstr
	condArr["filter"] = filter
	condArr["status"] = status
	condArr["keywords"] = keywords
	condArr["acceptid"] = acceptid
	condArr["type"] = typec
	condArr["level"] = level
	condArr["env"] = env
	condArr["completeid"] = completeid
	condArr["projectmoduleid"] = projectmoduleid
	condArr["group"] = group
	condArr["createStarted"] = createStarted
	condArr["createEnd"] = createEnd
	condArr["bussconfirmstatus"] = bussconfirmstatus
	condArr["estimatedtasktimestart"] = estimatedtasktimestart
	condArr["estimatedtasktimestartend"] = estimatedtasktimestartend
	condArr["testno"] = testno
	condArr["departid"] = departid
	dir := "/logs"
	StaticPath, _ := beego.AppConfig.String("StaticPath")
	mkdir := StaticPath + dir
	if !utils.FileExists(mkdir) {
		os.MkdirAll(mkdir, os.ModePerm)
	}
	f := excelize.NewFile()
	// 创建一个工作表
	index := f.NewSheet("Sheet1")
	projectsAllTest := TestExportExec(condArr)
	f.SetSheetRow("Sheet1", "A1", &[]interface{}{
		"项目名称", "反馈编号", "模块", "反馈标题", "反馈内容", "分类", "直接原因", "预估工时", "实际工时", "创建人", "指派人", "反馈状态", "级别", "反馈环境", "反馈时间", "根本原因", "创建人部门", "验收部门",
	})
	for i, test := range projectsAllTest {
		// 如果为0写入新的excel 第一行为字段名称
		// 设置单元格的值
		f.SetCellValue("Sheet1", fmt.Sprintf("A%d", i+2), test.Projectname)
		f.SetCellValue("Sheet1", fmt.Sprintf("B%d", i+2), fmt.Sprintf("%d", test.Id))
		f.SetCellValue("Sheet1", fmt.Sprintf("C%d", i+2), test.Modulename)
		f.SetCellValue("Sheet1", fmt.Sprintf("D%d", i+2), test.Name)
		f.SetCellValue("Sheet1", fmt.Sprintf("E%d", i+2), test.Desc)
		f.SetCellValue("Sheet1", fmt.Sprintf("F%d", i+2), dict.GetDictByTypeAndDictId_("TEST_TYPE", strconv.Itoa(test.Type), utils.ToInt64(idstr)).DictName)
		f.SetCellValue("Sheet1", fmt.Sprintf("G%d", i+2), test.DirectCause)
		f.SetCellValue("Sheet1", fmt.Sprintf("H%d", i+2), test.Estimatedtasktime)
		f.SetCellValue("Sheet1", fmt.Sprintf("I%d", i+2), test.Actualtasktime)
		f.SetCellValue("Sheet1", fmt.Sprintf("J%d", i+2), test.Userrealname)
		f.SetCellValue("Sheet1", fmt.Sprintf("K%d", i+2), test.Acceptrealname)
		f.SetCellValue("Sheet1", fmt.Sprintf("L%d", i+2), dict.GetDictByTypeAndDictId_("TEST_STATUS", strconv.Itoa(test.Status), utils.ToInt64(idstr)).DictName)
		f.SetCellValue("Sheet1", fmt.Sprintf("M%d", i+2), dict.GetDictByTypeAndDictId_("LEVEL", strconv.Itoa(test.Level), utils.ToInt64(idstr)).DictName)
		f.SetCellValue("Sheet1", fmt.Sprintf("N%d", i+2), dict.GetDictByTypeAndDictId_("ENV", strconv.Itoa(test.Env), utils.ToInt64(idstr)).DictName)
		f.SetCellValue("Sheet1", fmt.Sprintf("O%d", i+2), utils.GetDate(test.Created))
		f.SetCellValue("Sheet1", fmt.Sprintf("P%d", i+2), test.RootCause)
		f.SetCellValue("Sheet1", fmt.Sprintf("Q%d", i+2), test.Departname)
		f.SetCellValue("Sheet1", fmt.Sprintf("R%d", i+2), test.Uatdepartname)
	}
	// 设置工作簿的默认工作表
	f.SetActiveSheet(index)
	filename := mkdir + "/" + fmt.Sprintf("反馈%d", time.Now().Unix()) + ".xlsx"
	f.SaveAs(filename)
	this.Ctx.Output.Download(filename)
}

type TestBatchStatusDTO struct {
	Taskid []string
	Status int
}

// @Title batch Update  test status
// @Description batch Update  test status
// @Param	body	body 	projects.TestBatchStatusDTO	true		"Status 必填"
// @Success 200 {string} 更新成功
// @Failure 403 body is empty
// @router /batch/status [put]
func (u *TestProjectController) BatchUpdateStatus() {
	var dto TestBatchStatusDTO
	err := json.Unmarshal(u.Ctx.Input.RequestBody, &dto)
	if err != nil {
		u.Data["json"] = map[string]interface{}{"code": 0, "message": "json转换异常" + err.Error()}
		return
	}
	// 开始校验输入值
	valid := validation.Validation{}
	valid.Required(dto.Status, "Status").Message("状态不能为空")
	valid.Required(dto.Taskid, "Taskid").Message("任务id不能为空")
	b, err := valid.Valid(&dto)
	if err != nil {
		// handle error
		u.Data["json"] = map[string]interface{}{"code": 0, "message": "严重异常" + err.Error()}
		u.ServeJSON()
		return
	}
	if !b {
		var validMsg []string
		// validation does not pass
		for _, err := range valid.Errors {
			validMsg = append(validMsg, err.Message)
			log.Println(err.Key, err.Message)
		}
		if !utils.IsEmpty(validMsg) {
			u.Data["json"] = map[string]interface{}{"code": 0, "message": strings.Join(validMsg, ",")}
			u.ServeJSON()
			return
		}
	}
	for _, v := range dto.Taskid {
		TestStatus := new(ProjectsTestStatus)
		v1, _ := strconv.ParseInt(v, 10, 64)
		TestStatus.Id = v1
		TestStatus.Status = dto.Status
		TestStatus.IfsMail = 1
		err := ChangeProjectTest(u.UserUserId, *TestStatus)
		if err != nil {
			u.Data["json"] = map[string]interface{}{"code": 0, "message": "修改状态失败,反馈编号：" + fmt.Sprintf("%d", v)}
			u.ServeJSON()
			return
		}
	}
	u.Data["json"] = map[string]interface{}{"code": 1, "message": "修改状态成功"}
	u.ServeJSON()
}
